package com.senarai.thedemit;

import java.sql.Time;
import java.util.Date;

import javax.microedition.khronos.opengles.GL10;

import org.anddev.andengine.engine.Engine;
import org.anddev.andengine.engine.camera.Camera;
import org.anddev.andengine.engine.handler.IUpdateHandler;
import org.anddev.andengine.engine.options.EngineOptions;
import org.anddev.andengine.engine.options.EngineOptions.ScreenOrientation;
import org.anddev.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy;
import org.anddev.andengine.entity.scene.Scene;
import org.anddev.andengine.entity.scene.background.ColorBackground;
import org.anddev.andengine.entity.scene.background.SpriteBackground;
import org.anddev.andengine.entity.scene.menu.MenuScene;
import org.anddev.andengine.entity.scene.menu.MenuScene.IOnMenuItemClickListener;
import org.anddev.andengine.entity.scene.menu.item.IMenuItem;
import org.anddev.andengine.entity.scene.menu.item.SpriteMenuItem;
import org.anddev.andengine.entity.sprite.Sprite;
import org.anddev.andengine.entity.util.FPSLogger;
import org.anddev.andengine.entity.util.ScreenCapture;
import org.anddev.andengine.entity.util.ScreenCapture.IScreenCaptureCallback;

import andengineaugmentedrealityextension.*;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.hardware.Camera.AutoFocusCallback;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.ShutterCallback;
import android.util.Log;
import android.view.Display;
import android.widget.Chronometer;
import android.widget.Toast;
import bitmapextension.BitmapTextureAtlasSource;

import org.anddev.andengine.opengl.texture.TextureOptions;
import org.anddev.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlas;
import org.anddev.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlasTextureRegionFactory;
import org.anddev.andengine.opengl.texture.region.TextureRegion;
import org.anddev.andengine.sensor.accelerometer.AccelerometerData;
import org.anddev.andengine.sensor.accelerometer.IAccelerometerListener;
import org.anddev.andengine.util.FileUtils;

import com.senarai.thedemit.ghost.Ghost;

public class MainActivity extends BaseAugmentedRealityGameActivity implements IOnMenuItemClickListener, IAccelerometerListener {
	// ===========================================================
	// Constants
	// ===========================================================
	protected static final int MENU_CAPTURE = 0;
	protected static final int MENU_QUIT = MENU_CAPTURE + 1;
	
	// ===========================================================
	// Fields
	// ===========================================================
	private int CAMERA_WIDTH;
	private int CAMERA_HEIGHT;
	protected Scene mMainScene;
	private Camera mCamera;
	private float duration;
	private int score;
	private android.text.format.Time startTime;
	private android.text.format.Time endTime;
	
	//Object ghost : 
	private BitmapTextureAtlas mBitmapTextureAtlas;
	private TextureRegion mFaceTextureRegion;
	private Ghost ghost;
	long nextGhostTiming = 0;
	private float waitNextGhost = 0.0f;

	//Menu : Capture, Quit
	protected MenuScene mMenuScene;
	private BitmapTextureAtlas mMenuTexture;
	protected TextureRegion mMenuCaptureTextureRegion;
	protected TextureRegion mMenuQuitTextureRegion;
	
	//ImageTaken From Camera Scene :
	protected Scene imageTakenScene = new Scene();
	private BitmapTextureAtlas mImageTakenTexture;
	//private TextureRegion mImageTakenTextureRegion;
	
	//Screen Capturer :
	private Bitmap imageTaken;
	private ScreenCapture screenCapturer;
	private long ghostStartMove;
	protected long startTimeToWait;
	
	//Accelerometer Data :
	private float accelerometerZ;
	
	
	// ===========================================================
	// Constructors
	// ===========================================================

	// ===========================================================
	// Getter & Setter
	// ===========================================================

	// ===========================================================
	// Methods for/from SuperClass/Interfaces
	// ===========================================================

	public Engine onLoadEngine() {
		final Display display = getWindowManager().getDefaultDisplay();
		CAMERA_WIDTH = display.getWidth();
		CAMERA_HEIGHT = display.getHeight();
		startTime = new android.text.format.Time();
		endTime = new android.text.format.Time();
		
		this.mCamera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
		return new Engine(new EngineOptions(true, ScreenOrientation.LANDSCAPE, new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), this.mCamera));
	}

	public void onLoadResources() {
		this.enableAccelerometerSensor(this);
		BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/");
		
		ghost = new Ghost(0);
		this.mBitmapTextureAtlas = new BitmapTextureAtlas(256, 256, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
		this.mFaceTextureRegion = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mBitmapTextureAtlas, this, ghost.path, 0, 0);
		this.mEngine.getTextureManager().loadTexture(this.mBitmapTextureAtlas);
		
		this.mMenuTexture = new BitmapTextureAtlas(128, 128, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
		this.mMenuCaptureTextureRegion = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mMenuTexture, this, "shutter.png", 0, 0);
		this.mMenuQuitTextureRegion = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mMenuTexture, this, "quit.png", 0, 60);
		this.mEngine.getTextureManager().loadTexture(this.mMenuTexture);
	}

	public Scene onLoadScene() {
		this.mEngine.registerUpdateHandler(new IUpdateHandler() {

			public void reset() {
				// TODO Auto-generated method stub
				
			}
			
			public void onUpdate(float pSecondsElapsed) {
				long timenow = System.currentTimeMillis();
				if (ghost.sprite==null && timenow-startTimeToWait>=waitNextGhost && accelerometerZ < 3) {
					Log.d("demit","create baru "+(timenow-startTimeToWait)+"        "+waitNextGhost);
					createGhostScene();
					
					//Screen Capturer :
					MainActivity.this.screenCapturer = new ScreenCapture();
					MainActivity.this.mMainScene.attachChild(screenCapturer);
				}
				timenow = System.currentTimeMillis();
				if (ghost.sprite!=null && timenow-ghostStartMove>=duration*1000) {
					// ghost sudah habis
					Log.d("demit","ghost habis "+(timenow-ghostStartMove)+"        "+duration);
					waitNextGhost = 4000+Randomizer.randomizer(10000.0f);
					startTimeToWait = System.currentTimeMillis();
					ghost.sprite = null;
				}
			}
		});
		
		//Crate Main Scene : 
		this.mMainScene = new Scene();
		this.mMainScene.setBackground(new ColorBackground(0.0f, 0.0f, 0.0f, 0.0f));
		
		//Create Scene Menu :
		this.createMenuScene();
		
		return this.mMainScene;
	}

	public void onLoadComplete() {

	}

	
	// ===========================================================
	// Methods
	// ===========================================================
	private void createMenuScene() {
		this.mMenuScene = new MenuScene(this.mCamera);
		
		//Menu Capture
		final SpriteMenuItem captureMenuItem = new SpriteMenuItem(MENU_CAPTURE, this.mMenuCaptureTextureRegion);
		captureMenuItem.setBlendFunction(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
		this.mMenuScene.addMenuItem(captureMenuItem);

		//Menu quit
		final SpriteMenuItem quitMenuItem = new SpriteMenuItem(MENU_QUIT, this.mMenuQuitTextureRegion);
		quitMenuItem.setBlendFunction(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
		this.mMenuScene.addMenuItem(quitMenuItem);

		this.mMenuScene.buildAnimations();

		this.mMenuScene.setBackgroundEnabled(false);

		this.mMenuScene.setOnMenuItemClickListener(this);
		this.mMainScene.setChildScene(this.mMenuScene);
	}
	
	private void createGhostScene() {
		boolean bool = Randomizer.isGhostAppear() ;
		if (bool == true){
		final int centerX = (CAMERA_WIDTH - this.mFaceTextureRegion.getWidth()) / 2;
		final int centerY = (CAMERA_HEIGHT - this.mFaceTextureRegion.getHeight()) / 2;
		ghost.sprite = new Sprite(centerX, centerY, this.mFaceTextureRegion);
		//ghost.move(CAMERA_WIDTH,CAMERA_HEIGHT);
		//ghost.moveVertical(CAMERA_WIDTH,CAMERA_HEIGHT);
		//ghost.moveHorizontal(CAMERA_WIDTH,CAMERA_HEIGHT);
		ghostStartMove = System.currentTimeMillis();
		duration =  ghost.childrenThiefMove(CAMERA_WIDTH, CAMERA_HEIGHT);
		this.mMainScene.attachChild(ghost.sprite);
		startTime.setToNow();
		}
	}
	
	
	protected void takePicture() {
		//mCameraPreviewSurfaceView.mCamera.autoFocus(new AutoFocusCallback() {
			//public void onAutoFocus(boolean success, android.hardware.Camera camera) {
				mCameraPreviewSurfaceView.mCamera.takePicture(shutterCallback, rawCallback, jpegCallback);
				//	get score here
				getScore();
			//}
		//});
	}
	
	private void getScore(){
		endTime.setToNow();
		Log.d("pret", "start time : " + startTime);
		Log.d("pret", "end time : " + endTime);
		long captureDuration = endTime.toMillis(false) - startTime.toMillis(false);
		captureDuration /= 1000;
		Log.d("pret", "captutre duration : " + captureDuration);
	}
	
	ShutterCallback shutterCallback = new ShutterCallback() {
		public void onShutter() {
		}
	};

	/** Handles data for raw picture */
	PictureCallback rawCallback = new PictureCallback() {
		public void onPictureTaken(byte[] data, android.hardware.Camera camera) {
		}
	};

	/** Handles data for jpeg picture */
	PictureCallback jpegCallback = new PictureCallback() {
		public void onPictureTaken(byte[] data, android.hardware.Camera camera) {
			imageTaken = BitmapFactory.decodeByteArray(data, 0, data.length);
			captureImage();
		}
	};
	
	private void changeBackgroundFromImageTaken() {
		//ImageTaken di attach ke scene imageTakenScene :
		BitmapTextureAtlasSource source = new BitmapTextureAtlasSource(imageTaken);
		mImageTakenTexture = new BitmapTextureAtlas(1024, 1024);
		mImageTakenTexture.addTextureAtlasSource(source, 0, 0);
		this.mEngine.getTextureManager().loadTexture(mImageTakenTexture);
		TextureRegion mImageTakenRegion = new TextureRegion(mImageTakenTexture, 0, 0, mImageTakenTexture.getWidth(), mImageTakenTexture.getHeight());
		
		this.mMainScene.setBackground(new SpriteBackground(new Sprite(0, 0,mImageTakenRegion.getWidth(), mImageTakenRegion.getHeight(), mImageTakenRegion)));
	}
	
	private void captureImage(){
		if (imageTaken==null) {
			System.out.println("null");
		} else {
			System.out.println("GAK null");
			/* Change Background From Scene */
			changeBackgroundFromImageTaken();
			
			/* Capture SCENE */
			final int viewWidth = MainActivity.this.mRenderSurfaceView.getWidth();
			final int viewHeight = MainActivity.this.mRenderSurfaceView.getHeight();
			
			FileUtils.ensureDirectoriesExistOnExternalStorage(MainActivity.this,FileUtils.getAbsolutePathOnExternalStorage(MainActivity.this,""));
			this.screenCapturer.capture(viewWidth, viewHeight, FileUtils.getAbsolutePathOnExternalStorage(MainActivity.this, "Screen_"+System.currentTimeMillis()+".png"), new IScreenCaptureCallback() {
				
				public void onScreenCaptured(final String pFilePath) {
					/* MainActivity.this.runOnUiThread(new Runnable() {
						public void run() {
							Toast.makeText(MainActivity.this, "Screenshot: "+pFilePath+" taken!", Toast.LENGTH_SHORT).show();
						}
					});
					*/
					MainActivity.this.startActivity(new Intent(MainActivity.this, MainMenu.class));
					MainActivity.this.finish();
				}
				
				public void onScreenCaptureFailed(String pFilePath, Exception pException) {
					/* MainActivity.this.runOnUiThread(new Runnable() {
						public void run() {
							Toast.makeText(MainActivity.this, "FAILED capturing Screenshot", Toast.LENGTH_SHORT).show();
						}
					});
					*/
					
					MainActivity.this.startActivity(new Intent(MainActivity.this, MainMenu.class));
					MainActivity.this.finish();
				}
			});	
		}
	}

	
	public boolean onMenuItemClicked(MenuScene pMenuScene, IMenuItem pMenuItem,
			float pMenuItemLocalX, float pMenuItemLocalY) {
		switch(pMenuItem.getID()) {
			case MENU_CAPTURE:
				/* Capture */
				this.takePicture();
				return true;
			case MENU_QUIT:
				/* End Activity. */
				this.finish();
				return true;
			default:
				return false;
		}
	}

	public void onAccelerometerChanged(final AccelerometerData pAccelerometerData) {		
		accelerometerZ = pAccelerometerData.getZ();
	}
	
	// ===========================================================
	// Inner and Anonymous Classes
	// ===========================================================
}